home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 October: Mac OS SDK / Dev.CD Oct 00 SDK1.toast / Development Kits / Mac OS / Display Manager SDK / Sample Code / DisplayVideo68k / DisplayVideo.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-01-30  |  12.6 KB  |  362 lines  |  [TEXT/CWIE]

  1. /*------------------------------------------------------------------------------
  2. #
  3. #    MacOS™ Sample Code
  4. #    
  5. #    Written by: Eric Anderson
  6. #     email: eric3@apple.com
  7. #
  8. #    Display Manager sample code
  9. #
  10. #    DisplayVideo
  11. #
  12. #    DisplayVideo.c    -    C Source
  13. #
  14. #    Copyright © 1995-1999 Apple Computer, Inc.
  15. #    All rights reserved.
  16. #
  17. #    1/20/99        ewa        Updated to CWPro 3. Added refresh rate, timing flag
  18. #                        and mode flag information
  19. #    5/31/95        ewa        New today.
  20. #
  21. #    Components:    DisplayVideo.c            
  22. #
  23. #    DisplayVideo will display all info about all video modes supported by
  24. #    each installed video card with their attached monitor.
  25. #    The purpose of this code is to provide a sample of
  26. #    how developers can change the bit depth and timing of multisync
  27. #    displays under their own control.
  28. #    
  29. #
  30. ------------------------------------------------------------------------------*/
  31.  
  32. #include <Dialogs.h>
  33. #include <Devices.h>
  34. #include <Displays.h>
  35. #include <Errors.h>
  36. #include <FixMath.h>
  37. #include <fp.h>
  38. #include <Gestalt.h>
  39. #include <Memory.h>
  40. #include <Palettes.h>
  41. #include <PLStringFuncs.h>
  42. #include <QuickDraw.h>
  43. #include <ROMDefs.h>
  44. #include <Slots.h>
  45. #include <StdIO.h>
  46. #include <Video.h>
  47. #include <TextUtils.h>
  48. #include <Strings.h>
  49.  
  50. #include <SIOUX.h>
  51. #include <iostream>
  52.  
  53. #include <stdlib.h>
  54.  
  55. //--------------------------------------------------------------
  56. //
  57. // Internal defines, structs, typedefs, and routine declarations
  58. //
  59. //--------------------------------------------------------------
  60. struct DepthInfo {
  61.     VDSwitchInfoRec            depthSwitchInfo;            // This is the switch mode to choose this timing/depth
  62.     VPBlock                    depthVPBlock;                // VPBlock (including size, depth and format)
  63. };
  64. typedef struct DepthInfo DepthInfo;
  65.  
  66. struct ListIteratorDataRec {
  67.     unsigned long            displayModeFlags;            // 
  68.     VDSwitchInfoRec            displayModeSwitchInfo;        //
  69.     VDResolutionInfoRec        displayModeResolutionInfo;    //
  70.     VDTimingInfoRec            displayModeTimingInfo;        // Contains timing flags and such
  71.     unsigned long            depthBlockCount;            // How many depths available for a particular timing
  72.     DepthInfo                *depthBlocks;                // Array of DepthInfo
  73.     Str255                    displayModeName;            // name of the timing mode
  74. };
  75. typedef struct ListIteratorDataRec ListIteratorDataRec;
  76.  
  77. void PrintCurrentVideoSetting (GDHandle walkDevice);
  78.  
  79. void DisplayVideoSettings (void);
  80.  
  81. void PrintAvailableVideoSettingsDM2 (GDHandle walkDevice,
  82.                                 DMDisplayModeListIteratorUPP myModeIteratorProc,
  83.                                 DMListIndexType theDisplayModeCount,
  84.                                 DMListType *theDisplayModeList);
  85.  
  86. pascal void ModeListIterator (    void *userData,
  87.                                 DMListIndexType itemIndex,
  88.                                 DMDisplayModeListEntryPtr displaymodeInfo);
  89.  
  90. // routine implementations
  91. void main(void)
  92. {
  93.     SIOUXSettings.autocloseonquit = false;
  94.     SIOUXSettings.asktosaveonclose = false;
  95.     DisplayVideoSettings ();
  96. }
  97.  
  98.  
  99. //--------------------------------------------------------------
  100. //
  101. // Implementation of sample code
  102. //
  103. //--------------------------------------------------------------
  104. void PrintCurrentVideoSetting (GDHandle walkDevice)
  105. {
  106.     unsigned long        displayMgrVersion;
  107.     OSErr                error = paramErr;
  108.     CntrlParam            pBlock;
  109.     VDSwitchInfoRec        switchInfo;
  110.     AuxDCEHandle        theDCE;
  111.     VDSwitchInfoRec        videoMode;        
  112.  
  113.     Gestalt(gestaltDisplayMgrVers, (long*)&displayMgrVersion);
  114.     if (displayMgrVersion >= 0x00020000)
  115.     {    // get the info the DM 2.0 way
  116.         error = DMGetDisplayMode(walkDevice, &switchInfo);
  117.         if (noErr == error)
  118.         {
  119.             printf ("Current Settings DM2 - displayMode: %d, depthMode: %d\n", switchInfo.csData, switchInfo.csMode);
  120.         }
  121.     }
  122.     return;
  123. }
  124.  
  125.  
  126. void DisplayVideoSettings (void)
  127. {
  128.     Boolean                            displayMgrPresent;
  129.     short                            iCount = 0;                    // just a counter of GDevices we have seen
  130.     DMDisplayModeListIteratorUPP    myModeIteratorProc = nil;    // for DM2.0 searches
  131.     SpBlock                            spBlock;
  132.     Boolean                            suppliedGDevice;    
  133.     DisplayIDType                    theDisplayID;                // for DM2.0 searches
  134.     DMListIndexType                    theDisplayModeCount;        // for DM2.0 searches
  135.     DMListType                        theDisplayModeList;            // for DM2.0 searches
  136.     long                            value = 0;
  137.     GDHandle                        walkDevice = nil;            // for everybody
  138.  
  139.     Gestalt(gestaltDisplayMgrAttr,&value);
  140.     displayMgrPresent=value&(1<<gestaltDisplayMgrPresent);
  141.     displayMgrPresent=displayMgrPresent && (SVersion(&spBlock)==noErr);    // need slot manager
  142.     if (displayMgrPresent)                                                // and Display Manager
  143.     {    
  144.         walkDevice = DMGetFirstScreenDevice (dmOnlyActiveDisplays);            // for everybody
  145.         suppliedGDevice = false;
  146.         
  147.         myModeIteratorProc = NewDMDisplayModeListIteratorProc(ModeListIterator);    // for DM2.0 searches
  148.     
  149.         // Note that we are hosed if somebody changes the gdevice list behind our backs while we are iterating....
  150.         // ...now do the loop if we can start
  151.         if( walkDevice && myModeIteratorProc) do // start the search
  152.         {
  153.             iCount++;        // GDevice we are looking at (just a counter)
  154.             printf("=================================================\n");
  155.             printf("GDevice #%d (0x%X) at location (%d,%d).\n",iCount, *walkDevice, (long )(*walkDevice)->gdRect.left, (long )(*walkDevice)->gdRect.top);
  156.             printf("=================================================\n\n");
  157.  
  158.             PrintCurrentVideoSetting (walkDevice);
  159.             
  160.             if( noErr == DMGetDisplayIDByGDevice( walkDevice, &theDisplayID, false ) )    // DM1.0 does not need this, but it fits in the loop
  161.             {
  162.                 theDisplayModeCount = 0;    // for DM2.0 searches
  163.                 if (noErr == DMNewDisplayModeList(theDisplayID, 0, 0, &theDisplayModeCount, &theDisplayModeList) )
  164.                 {
  165.                     // search video devices the new kool way through Display Manager 2.0
  166.                     PrintAvailableVideoSettingsDM2 (walkDevice, myModeIteratorProc, theDisplayModeCount, &theDisplayModeList);
  167.                     DMDisposeList(theDisplayModeList);    // now toss the lists for this gdevice and go on to the next one
  168.                 }
  169.             }
  170.  
  171.             printf("\n\n\n");
  172.  
  173.         } while ( !suppliedGDevice && nil != (walkDevice = DMGetNextScreenDevice ( walkDevice, dmOnlyActiveDisplays )) );    // go until no more gdevices
  174.         if( myModeIteratorProc )
  175.             DisposeRoutineDescriptor(myModeIteratorProc);
  176.         return;
  177.     }
  178. }
  179.  
  180. pascal void ModeListIterator(void *userData, DMListIndexType, DMDisplayModeListEntryPtr displaymodeInfo)
  181. {
  182.     unsigned long            depthCount;
  183.     short                    iCount;
  184.     ListIteratorDataRec        *myIterateData        = (ListIteratorDataRec*) userData;
  185.     DepthInfo                *myDepthInfo;
  186.     
  187.     long                    length = 0;
  188.     
  189.     // set display data in a round about way
  190.     // Set the basics
  191.     myIterateData->displayModeFlags                = displaymodeInfo->displayModeFlags;        // for mode flags
  192.     myIterateData->displayModeSwitchInfo        = *displaymodeInfo->displayModeSwitchInfo;    // not needed - depth info has this per depth
  193.     myIterateData->displayModeResolutionInfo    = *(VDResolutionInfoRec *)displaymodeInfo->displayModeResolutionInfo;    // refresh rate, pixels/lines at max depth 
  194.     myIterateData->displayModeTimingInfo        = *displaymodeInfo->displayModeTimingInfo;    // for iming flags
  195.     
  196.     BlockMoveData ((StringPtr)displaymodeInfo->displayModeName,(StringPtr)&myIterateData->displayModeName, ((StringPtr)displaymodeInfo->displayModeName)[0]+1);    // the name of the mode
  197.     
  198.     // now get the DMDepthInfo into memory we own
  199.     depthCount = displaymodeInfo->displayModeDepthBlockInfo->depthBlockCount;
  200.     myDepthInfo = (DepthInfo*)NewPtrClear(depthCount * sizeof(DepthInfo));
  201.  
  202.     // set the info for the caller
  203.     myIterateData->depthBlockCount = depthCount;
  204.     myIterateData->depthBlocks = myDepthInfo;
  205.  
  206.     // and fill out all the entries
  207.     if (depthCount) for (iCount=0; iCount < depthCount; iCount++)
  208.     {
  209.         myDepthInfo[iCount].depthSwitchInfo = 
  210.             *displaymodeInfo->displayModeDepthBlockInfo->depthVPBlock[iCount].depthSwitchInfo;
  211.         myDepthInfo[iCount].depthVPBlock = 
  212.             *displaymodeInfo->displayModeDepthBlockInfo->depthVPBlock[iCount].depthVPBlock;
  213.     }
  214. }
  215.  
  216. void PrintAvailableVideoSettingsDM2 (GDHandle walkDevice,
  217.                             DMDisplayModeListIteratorUPP myModeIteratorProc,
  218.                             DMListIndexType theDisplayModeCount,
  219.                             DMListType *theDisplayModeList)
  220. {
  221.     short                    jCount;
  222.     short                    kCount;
  223.     ListIteratorDataRec        searchData;
  224.     double_t                refreshRate;
  225.     unsigned long            switchFlags;
  226.     Boolean                    modeOk;
  227.     OSErr                    error;
  228.  
  229.     searchData.depthBlocks = nil;
  230.     // get the mode lists for this GDevice
  231.     for (jCount=0; jCount<theDisplayModeCount; jCount++)        // get info on all the resolution timings
  232.     {
  233.         DMGetIndexedDisplayModeFromList(*theDisplayModeList, jCount, 0, myModeIteratorProc, &searchData);
  234.         
  235.         // for all the depths for this resolution timing (mode)...
  236.         printf("\nTiming mode: %d (or  0x%X) named “%s”\n",
  237.                     searchData.depthBlocks[0].depthSwitchInfo.csData,
  238.                     searchData.depthBlocks[0].depthSwitchInfo.csData,
  239.                     P2CStr(searchData.displayModeName));
  240.     
  241.         refreshRate = Fix2X (searchData.displayModeResolutionInfo.csRefreshRate);
  242.  
  243.         if ( round (refreshRate) == 0)
  244.                 printf ("Refresh rate: 0 (not defined in displayModeResolutionInfo.csRefreshRate)\n");
  245.         else
  246.         {
  247.             Str255            refreshStr;
  248.             decform            theFormat;
  249.             decimal            theNumeric;
  250.             
  251.             theFormat.style = FIXEDDECIMAL;
  252.             theFormat.unused = 0;
  253.             theFormat.digits = 4;
  254.             
  255.             num2dec (&theFormat, refreshRate, &theNumeric );
  256.             dec2str ( &theFormat, &theNumeric, (char *)refreshStr );
  257.             printf ("Refresh rate: %s\n", refreshStr);
  258.         }
  259.         
  260.         if (searchData.displayModeResolutionInfo.csResolutionFlags & 1<<kResolutionHasMultipleDepthSizes)
  261.                 printf("DisplayMode has different H&V per bit depth\n");
  262.  
  263.         {
  264.             char        tempArr[6];
  265.             ResType*    tempPtr = (ResType* )&tempArr[0];                    // Make a convenient ptr to assign the restype
  266.             *tempPtr = searchData.displayModeTimingInfo.csTimingFormat;        // contents of string are the resType
  267.             tempArr[4] = 0;                                                    // null temp the string
  268.             printf("Timing format: “%s”. Timing csData %d\n", tempArr, searchData.displayModeTimingInfo.csTimingData);
  269.         }
  270.         
  271.         printf("Available depths:\n");
  272.  
  273.  
  274.         if (searchData.depthBlockCount) for (kCount = 0; kCount < searchData.depthBlockCount; kCount++)
  275.         {
  276.             // print all the timing information 
  277.             printf("    Depth: %d, Depth mode: 0x%X, Resolution: %dH x %dV\n",
  278.                 searchData.depthBlocks[kCount].depthVPBlock.vpPixelSize,
  279.                 searchData.depthBlocks[kCount].depthSwitchInfo.csMode,
  280.                 searchData.depthBlocks[kCount].depthVPBlock.vpBounds.right,
  281.                 searchData.depthBlocks[kCount].depthVPBlock.vpBounds.bottom);
  282.     //        printf("Components per Pixel: %d, bits per Component: %d\n",
  283.     //            searchData.depthBlocks[kCount].depthVPBlock.vpCmpCount,
  284.     //            searchData.depthBlocks[kCount].depthVPBlock.vpCmpSize);
  285.                 
  286.  
  287.         }
  288.         
  289.         // Switch Flags
  290.         error = DMCheckDisplayMode(walkDevice,
  291.                     searchData.depthBlocks[0].depthSwitchInfo.csData,
  292.                     searchData.depthBlocks[0].depthSwitchInfo.csMode,
  293.                     &switchFlags,
  294.                     0,
  295.                     &modeOk);
  296.                     
  297.         if (noErr == error && modeOk)
  298.         {
  299.             printf("Switch Flags = 0x%X\n", switchFlags);
  300. //                if (switchFlags & 1<<kNoSwitchConfirmBit)
  301. //                        printf("      Confirmation not required,\n");
  302. //                else    printf("      Confirmation required,\n");
  303.  
  304. //                if (switchFlags & 1<<kDepthNotAvailableBit)
  305. //                        printf("      Current depth not available in this mode,\n");
  306. //                else    printf("      Current depth available in this mode,\n");
  307.  
  308. //                if (switchFlags & 1<<kShowModeBit)
  309. //                        printf("      Always shown,\n");
  310. //                else    printf("      Not always shown,\n");
  311.  
  312. //                if (switchFlags & 1<<kModeNotResizeBit)
  313. //                        printf("      Not resizeable,\n");
  314. //                else    printf("      Resizeable\n");
  315.         }
  316.  
  317.         // Timing Flags
  318.         printf("Timing Flags = 0x%X\n",searchData.displayModeTimingInfo.csTimingFlags);
  319.  
  320.         if (searchData.displayModeTimingInfo.csTimingFlags & 1<<kModeValid)
  321.                 printf("      Valid,\n",searchData.displayModeTimingInfo.csTimingFlags);
  322.         else    printf("      Invalid,\n",searchData.displayModeTimingInfo.csTimingFlags);
  323.  
  324.         if (searchData.displayModeTimingInfo.csTimingFlags & 1<<kModeSafe)
  325.                 printf("      Safe,\n");
  326.         else    printf("      Unsafe,\n");
  327.  
  328.         if (searchData.displayModeTimingInfo.csTimingFlags & 1<<kModeDefault)
  329.                 printf("      Default,\n");
  330.         else    printf("      Not default,\n");
  331.  
  332.         if (searchData.displayModeTimingInfo.csTimingFlags & 1<<kModeShowNow)
  333.                 printf("      Always shown,\n");
  334.         else    printf("      Not always shown,\n");
  335.             
  336. //            if (searchData.displayModeTimingInfo.csTimingFlags & 1<<kModeNotResize)
  337. //                    printf("      Not resizeable,\n");
  338. //            else    printf("      Resizeable,\n");
  339.         
  340. //            if (searchData.displayModeTimingInfo.csTimingFlags & 1<<kModeRequiresPan)
  341. //                    printf("      Requires pan.\n");
  342. //            else    printf("      No pan.\n");
  343.             
  344.         if (searchData.displayModeTimingInfo.csTimingFlags & 1<<kModeInterlaced)
  345.                 printf("      Interlaced.\n");
  346.             
  347.         // Mode Flags
  348.         printf("Mode Flags = 0x%X\n",searchData.displayModeFlags);
  349.         if (searchData.displayModeFlags & 1<<0)
  350.             printf("      Stripped,\n");                // does not show up in "Recomended" list of timings
  351.         else
  352.             printf("      Not Stripped,\n");            // Is a recomended timing
  353.  
  354.         if (searchData.depthBlocks)
  355.         {
  356.             DisposePtr ((Ptr)searchData.depthBlocks);    // toss for this timing mode of this gdevice
  357.             searchData.depthBlocks = nil;                // init it just so we know
  358.         }
  359.     }
  360. }
  361.  
  362.